TITL DAI FIRMWARE 2E5FC-2E7FB V1.1 ORG :E5FC * * * ******************************* * INITIALISE HEADER / TRAILER * ******************************* * * Sets up 4 background colour lines which can act * as header/trailer. Sets up colours in colour RAM. * The header/trailer area consists of 4 groups of * 4 bytes: 00 00 xx 3x, in which xx is the colour * and 3x the mode word: * x=6: Header. * x=F: Trailer. * x=0: Middle area (split mode). * * Entry: HL: 1st byte header/trailer area. * DE: Address table with required colours. * A : Screen mode. * B : Depth -1 in scans of each blanking * line: 06 (header), 0F (trailer), * 00 (middle). * Exit: HL: Points after header/trailer area. * AFBCDE preserved. * SSUBL PUSH PSW PUSH B PUSH D MOV C,A Store screen mode in C MOV A,B ORI :30 Set 4 colour to make mode REM word + rept.count PUSH PSW Save mode word on stack MVI B,:00 MOV A,E Get lobyte addr colours SUI :7C JZ :E61E If char mode then 4 colours MOV A,C Get screen mode RAR RAR MOV C,B JC :E61F Jump if 4-colour mode REM * 16-colour modes only: REM POP PSW Restore header/trailer info ORI :80 Set 16-colour (msb=1) PUSH PSW LDAX D Get colour ADD A ) ADD A ) Move lonibble into ADD A ) hinibble ADD A ) MVI B,:FF Set all foreground SBL10 MOV C,A Colour in C REM * Load header/trailer: REM SBL20 POP PSW Get mode word PUSH PSW MOV M,A Load 1st byte pointer DCX H Next addr in block LDAX D Get colour info INX D MOV M,A Load 2nd byte DCX H Next addr in block MOV M,B Load 3rd byte DCX H MOV M,C Load 4th byte DCX H CPI :B0 All blocks done ? JC :E61F Next one if not POP PSW POP D POP B POP PSW RET * ***************************** * SET UP A 4-LINE TEXT AREA * ***************************** * * Locates the last few lines of text on the * screen. If the screen was in split mode, the * whole contents of the old screen is located. * If it was mode 0, the last few lines above * and the cursor line are located. * The text is then moved to a required position, * including the cursor, etc. * * Entry: HL: Points to address where the text to * be put. * Exit: HL: Points to new top of text. * AFBCDE preserved. * SMVTXT PUSH PSW PUSH B PUSH D MOV B,H ) New top of text in BC MOV C,L ) LHLD :009B Get previous start char PUSH H on stack XCHG and in DE LXI H,:FDE8 Length split screen char REM area DAD D Calc 1st line mode byte REM outside screen frame XCHG in DE LHLD :0072 Get cursor pos addr CALL :E6FB Check if cursor is still REM inside frame JC :E675 Jump if not XCHG HL is addr 1st line mode REM outside screen frame POP D DE is prev start char SMV10 PUSH H Save end preserved text area LHLD :0072 Get cursor pos addr CALL :E36B Delete cursor XTHL Previous start char in HL CALL :E6C2 Roll screen area to new top REM of text; cursor on last line XTHL Cursor pos in HL CALL :E6F2 Calc cursor pos against new REM frame start DAD B Calc new cursor pos addr CALL :E330 Keep cursor on same pos on REM line LHLD :0078 Get old start line pointer CALL :E6F2 HL=HL-DE DAD B Calc new cursor pos CALL :E698 Store addr line mode byte REM current line and last addr REM on that line POP H Get end preserved text area CALL :E6F2 HL=HL-DE DAD B POP D POP B POP PSW RET REM * Scroll frame 1 line if cursor outside frame: REM SMV20 POP H LHLD :0078 Get startaddr cursor line LXI D,:FF7A DAD D HL: start line after cursor PUSH H LXI D,:0218 DAD D Subtract 4 lines and get XCHG line mode byte in DE POP H Get end reqd area JMP :E64F * ********************************* * PLACE CURSOR AT BEGIN OF LINE * ********************************* * * Sets the cursor at the beginning of a line. * Several pointers are updated. * * SSETC: Given a pointer to the start of line, * sets start and end line variables and * places the cursor at the beginning of * the line. * SSETL: Sets only start and end line positions. * * Entry: HL: Address line mode byte current line. * Exit: ABCDEHL preserved. * SSETC PUSH PSW PUSH D PUSH H LXI D,:FFF8 DAD D Get addr 1st data byte REM on current line CALL :E330 Put cursor on screen XRA A STA :007B No extended lines POP H POP D POP PSW SSETL PUSH PSW SHLD :0078 Store addr line mode byte REM current line MVI A,:80 ) Calc lobyte last addr ADD L ) on this line STA :007A Store it in LNEND POP PSW RET * ************************ * SET GRAPHICS COLOURS * ************************ * * Sets the colours available in a 4 colour mode * and the initial background in a 16 colour mode. * * Entry: HL: Points to colours vector. * Exit: All registers preserved. * SCOLG PUSH PSW PUSH B PUSH D PUSH H LXI D,:009E Addr 1st COLORG byte CALL :E254 Set COLORG parameters LDA :009D Get current screen mode ORA A Check mode type LHLD :0082 Get addr after header CP :E267 If not mode 0: Load COLORG REM parameters in header RAR Check if char mode LHLD :008E Get addr after trailer CNC :E267 If all graphics mode: REM Load colours in trailer SGC10 JMP :E138 Popall, ret * ******************** * MOVE SCREEN AREA * ******************** * * Moves a block of screen data from any position * to any other. * * Entry: BC: Points to highaddress target area. * DE: Points to highaddress source area. * HL: Points to lowaddress -1 source area. * Exit: All registers preserved. * MOVES PUSH PSW PUSH B PUSH D PUSH H CALL :E6F2 Calc length of block REM (neg.value) MOV A,E SUB C MOV A,D SBB B JC :E6E2 Jump if move up REM * Move down: REM MOV D,H ) Length in DE MOV E,L ) DAD B HL = lowest targetaddr -1 POP B BC = lowest sourceaddr -1 PUSH B MVS10 MOV A,D ORA E JZ :E6EF Abort if ready INX D INX H INX B LDAX B Get byte from source area MOV M,A and move it into target area JMP :E6D5 Next one REM * Move up: REM MVS20 MOV A,H ORA L JZ :E6EF Quit if ready INX H LDAX D Get byte from source area STAX B Move it into target area DCX B DCX D JMP :E6E2 Next one * MVS40 JMP :E138 Popall, ret * **************** * HL = HL - DE * **************** * * Entry: None. * Exit: HL=HL-DE. * Other registers preserved. * SUBDE PUSH PSW MOV A,L SUB E MOV L,A L=L-E MOV A,H SBB D MOV H,A H=H-D POP PSW RET * ******************* * COMPARE HL - DE * ******************* * * Compares HL with DE (HL-DE). * * Exit: Z=0: Not identical: * CY=0: DE < HL. * CY=1: DE > HL. * Z=1: Identical. * AF corrupted, BCDEHL preserved. * COMP MOV A,H SUB D RNZ MOV A,L SUB E RET * ************************* * ADD OFFSET TO ADDRESS * ************************* * * Sets HL = HL + A. * * Entry: HL: baseaddress. * A : offset. * Exit: HL = HL + A. * BCDE preserved. * DADA ADD L Add lobyte addr to offset MOV L,A and store it in L RNC INR H Incr hibyte if overflow RET * ********************************** * TWO COMPLEMENT OF 16-BITS DATA * ********************************** * * Sets HL = - HL. * * Entry: Data to be complemented in HL. * Exit: HL contains two-complement. * AFBCDE preserved. * CMPHL PUSH PSW MOV A,L CMA Compl. L MOV L,A and store it MOV A,H CMA Compl. H MOV H,A and store it INX H Add 1 POP PSW RET * **************************** * DRAW A DOT ON THE SCREEN * **************************** * * Draws a single blob of a colour anywhere * on the screen. * * Entry: C,HL: Y,X coordinate of the dot. * A: Colour of the dot. * Exit: CY=0: O.K. * CY=1: Error code in A. * ABCDEHL preserved. * SDOT ORA A PUSH PSW PUSH B PUSH D PUSH H MOV B,C Y-coord in B MOV D,H ) X-coord in DE MOV E,L ) JMP :E81D Into 'SFILL' * ***************************** * DRAW A LINE ON THE SCREEN * ***************************** * * Draws a line in a given colour between two * arbitrary points on the screen. * * The coordinates are given inclusively. The * line will be drawn starting at the left end, * whichever order the parameters are given in. * * Entry: B,DE: Y,X coordinate of one end of the * line. * C,HL: Idem of the other end. * A: Colour of the line. * Exit: CY=0: O.K. * CY=1: Errorcode in A. * ABCDEHL preserved. * SDRAW ORA A PUSH PSW PUSH B PUSH D PUSH H CALL :E83A Check arguments, set colour PUSH PSW CALL :E6FB Check direction of line MVI A,:00 Set 'no X,Y swop' JNC :E72E Jump if X > Y REM * Swop X,Y: REM XCHG Exchange X coordinates CMA * DRL30 STA :00C0 FF if X,Y swop, else 00 MOV A,C ANI :07 MOV D,A Offset in field in D POP PSW Get Y-pos left end PUSH H Save X length CALL :EBB9 Pntr to start of line in REM screen RAM XTHL PUSH D Save offset PUSH H Save DX CALL :E706 HL = - DX XTHL PUSH H Save DX MOV L,E MVI H,:00 DAD H SHLD :00B9 Store 2*DY (adj long REM sectors) MOV A,E DY in A STA :00BD Set count of sectors (1-256) POP H CALL :EB60 HL = DX / DY SHLD :00BB SECT is INT(DX/DY) POP B Get -DX PUSH H Save SECT MOV A,E CALL :EB46 HL = SECT*DY DAD B HL = SECT*DY-DX DAD H HL = 2*(SECT*DY-DX) SHLD :00B5 Store amount to add into REM count POP H Get SECT MOV A,H RAR MOV A,L RAR A=INT(SECT/2) STA :00BE Store amount to trim off REM last sector INR A MOV L,A MVI H,:00 HL = INIT PUSH H DAD H HL = 2*INIT MOV A,E CALL :EB46 HL = 2*INIT*DY DAD B HL = 2*INIT*DY-DX SHLD :00B7 Set INIT running total POP H Get length 1st sector POP PSW MOV C,A C is initial offset MOV A,E ORA A JNZ :E784 If more than 1 sector STA :00BE Store amount to trim off REM last sector LHLD :00BB Get lower of 2 possible REM sectors INX H Prig length if only 1 sector DRL40 LXI D,:00BD Addr of nr of sectors LDAX D Get count of sectors SUI :01 -1 STAX D Store it again JNC :E797 Jump if not last sector REM * Trim off last sector: REM LDA :00BE Get amount to trim off REM last sector CMA MOV E,A MVI D,:FF INX D DAD D * DRL50 LXI D,:0001 Init Y-size is 1 LDA :00C0 ) Check if swop X,Y dir. ORA A ) (line > 45 degrees) JZ :E7A2 Jump if not XCHG Swop X,Y direction DRL60 MOV B,E Get Y-size in B XCHG X-size in DE POP H Get memory pointer DCR B LDA :00BF ) Check for Y-invert ORA A ) PUSH PSW Save condition CNZ :E7FC Move pntr to bottom of REM sector DCX D Interfacing CALL :EAF7 Draw next sector of line INX D ) Re-instate real values INR B ) POP PSW Get earlier condition JZ :E7BA Jump if no Y-invert MVI B,:01 Init 1 blob down only DRL80 CALL :E7FC Move ptr up/down MOV A,C Get offset ADD E Add X-movement MOV C,A ) Save result MOV B,A ) ANI :07 CMP C JZ :E7D2 Jump if not new field REM * If new field: REM MOV C,A Update offset MOV A,B Get complement new offset XRA C Clip bits 0,1,2 off RAR ) RAR ) CMA ) Update pointer MOV E,A ) to new field MVI D,:FF ) INX D ) DAD D ) * DRL83 PUSH H Save memory pointer LHLD :00B5 Get amount to add into count XCHG in DE LHLD :00B7 Get count running total DAD D Add up XCHG Result in DE LHLD :00BB Get lowest of 2 possible REM sectors XCHG in DE (distance to go) MOV A,H ORA A JP :E7ED Jump if short sector REM * If long sector: REM INX D Go one blob further PUSH D XCHG LHLD :00B9 Get adjustment for long REM sectors DAD D Adjust error term POP D DRL86 SHLD :00B7 Update running total XCHG LDA :00BD Get nr of sectors INR A JNZ :E784 Next sector if not ready REM * If ready: REM POP H JMP :E138 Popall, ret * * * END